﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EventReader.Controls;
using HenIT.RTF;
using System.Collections;
using System.Data;

namespace EventScavenger
{
    public partial class MainForm : Form
    {
        #region Constructor
        public MainForm()
        {
            InitializeComponent();
        } 
        private void SetAppTitle()
        {
            this.Text = "Event Scavenger viewer - " + Application.ProductVersion;
            toolStripStatusLabelDB.Text = "SRV\\DB:" + Properties.Settings.Default.SQLServer + @"\" + Properties.Settings.Default.Database;
#if DEBUG
            this.Text += " - DEBUG";
#endif
        }
        #endregion

        public void SetInitialView(string viewFile)
        {
            if (!Properties.Settings.Default.PredefineViewPaths.Contains(viewFile))
            {
                Properties.Settings.Default.PredefineViewPaths.Add(viewFile);
            }
            initialViewOnStartUp = viewFile;
        }

        #region Private members
        private EventScavengerDAL sqlEventSource = new EventScavengerDAL();
        private EventLogDetailView eventLogDetailView;
        private EventAnalizer eventAnalizer;
        private List<EventEntry> list = new List<EventEntry>();
        private List<MachineLogEntry> highLightMachineLogs = new List<MachineLogEntry>();
        private List<int> highLightIds = new List<int>();
        private List<string> highLightSources = new List<string>();
        private Color highLightColor = Color.LightBlue;
        private bool initializing = false;
        private bool autoUpdate = false;
        private string searchStr = "";
        private int refreshCount = 0;
        private const int MAXPREVIEWDISPLAYCOUNT = 100;
        private int minPieRestPerc = 3;
        private int filterExpandedSize = 180;
        private int filterCollapsedSize = 30;
        private string initialViewOnStartUp = "";
        #endregion

        #region Form events
        private void MainForm_Load(object sender, EventArgs e)
        {
            cmdFilterPanelSizeToggle.Visible = false;
            cmdToggleHideDetails.Visible = false;

            #region Set up control defaults
            splitContainerProfilesList.Panel1Collapsed = true;
            splitContainer1.Panel2Collapsed = true;
            toolStripHighLights.Visible = false;
            toolStripButtonAutoUpdate.Visible = Properties.Settings.Default.ViewAutoRefresh;
            toolStripLabelRate.Visible = Properties.Settings.Default.ViewAutoRefresh;
            rateToolStripComboBox.Visible = Properties.Settings.Default.ViewAutoRefresh;

            cboMaxEntriesFilter.SelectedIndex = 1;
            cboTypeFilter.SelectedIndex = 0;
            rateToolStripComboBox.SelectedIndex = 1;
            cboMaxEntriesFilter.Text = Properties.Settings.Default.TopViewCount.ToString();
            autoRefreshVisibleToolStripMenuItem1.Checked = Properties.Settings.Default.ViewAutoRefresh;

            fromDateTimeChooser.SelectedDateTime = DateTime.Now.AddDays(-3);
            toDateTimeChooser.SelectedDateTime = DateTime.Now;
            txtTextSearch.Text = Properties.Settings.Default.LastTextFilter;
            searchFullTextToolStripMenuItem.Checked = Properties.Settings.Default.FullTextSearchOnFind;
            #endregion

            #region Windows title
            SetAppTitle();
            #endregion

            SetGroupByToolStripChecks((ItemsGroupBy)Properties.Settings.Default.ItemsGroupBy);

            initializing = true;

            #region Windows location and size
            if (!Properties.Settings.Default.MainFormSize.Equals(new Size(0, 0)))
            {
                this.Size = Properties.Settings.Default.MainFormSize;
            }
            if (!Properties.Settings.Default.MainFormLocation.Equals(new Point(0, 0)))
            {
                this.Location = Properties.Settings.Default.MainFormLocation;
            }
            #endregion

            #region Text search history
            txtTextSearch.AutoCompleteCustomSource = new AutoCompleteStringCollection();
            if (Properties.Settings.Default.TextSearchHistoryList == null)
                Properties.Settings.Default.TextSearchHistoryList = new System.Collections.Specialized.StringCollection();
            foreach (string textSearch in Properties.Settings.Default.TextSearchHistoryList)
            {
                txtTextSearch.AutoCompleteCustomSource.Add(textSearch);
            } 
            #endregion

            #region Set up DAL
            sqlEventSource.Server = Properties.Settings.Default.SQLServer;
            sqlEventSource.Database = Properties.Settings.Default.Database;
            sqlEventSource.UserName = Properties.Settings.Default.UserName;
            sqlEventSource.Password = Properties.Settings.Default.Password;
            sqlEventSource.CommandTimeout = Properties.Settings.Default.SQLCMDTimeOut;
            sqlEventSource.SetConnection();
            sqlEventSource.MaxCount = Properties.Settings.Default.TopViewCount;

            //sqlEventSource.ShowAllMachineLogs = Properties.Settings.Default.ShowAllMachineLogs;
            //if (!sqlEventSource.ShowAllMachineLogs)
            //{
            //    if (Properties.Settings.Default.MachineLogFilter != null)
            //    {
            //        foreach (string machineLog in Properties.Settings.Default.MachineLogFilter)
            //        {
            //            if (machineLog.Contains("\\"))
            //            {
            //                sqlEventSource.MachineLogFilters.Add(sqlEventSource.GetMachineLogEntry(machineLog.Split('\\')[0], machineLog.Split('\\')[1]));
            //            }
            //        }
            //    }
            //    else
            //    {
            //        Properties.Settings.Default.MachineLogFilter = new System.Collections.Specialized.StringCollection();
            //    }
            //} 
            #endregion
            
            eventLogDetailView = new EventLogDetailView();
            eventLogDetailView.NavigateToItem += new EventLogDetailView.NavigateToItemDelegate(eventLogDetailView_NavigateToItem);

            #region Set up listTextBoxes
            listTextBoxMLE.ListTextBoxFormatter = new HenIT.Controls.ListTextBoxFormatterDelegate(FormatMLE);
            listTextBoxMLE.PrepareInput += new HenIT.Controls.PrepareInputDelegate(listTextBoxMLE_PrepareInput);
            listTextBoxMLE.ParseOutput += new HenIT.Controls.ParseOutputDelegate(listTextBoxMLE_ParseOutput);
            DisplaySelectedMLEs();
            listTextBoxSource.ListTextBoxFormatter = new HenIT.Controls.ListTextBoxFormatterDelegate(FormatSource);
            listTextBoxSource.PrepareInput += new HenIT.Controls.PrepareInputDelegate(listTextBoxSource_PrepareInput);
            listTextBoxSource.ParseOutput += new HenIT.Controls.ParseOutputDelegate(listTextBoxSource_ParseOutput);
            DisplaySelectedSources();
            listTextBoxEventID.ListTextBoxFormatter = new HenIT.Controls.ListTextBoxFormatterDelegate(FormatEventID);
            listTextBoxEventID.PrepareInput += new HenIT.Controls.PrepareInputDelegate(listTextBoxEventID_PrepareInput);
            listTextBoxEventID.ParseOutput += new HenIT.Controls.ParseOutputDelegate(listTextBoxEventID_ParseOutput);
            #endregion

            chkStayUpToDate.Checked = Properties.Settings.Default.StayUpToDateRefresh;
            panFilters.Height = filterCollapsedSize;

            //Only Vista and forward allows collaps of ListViewGroups
            if (Environment.OSVersion.Version.Major < 6)   
            {
                expandAllToolStripMenuItem.Visible = false;
                collapseAllToolStripMenuItem.Visible = false;
                toolStripSeparatorGroupBy.Visible = false;
            }

            new System.Threading.Thread(delegate()
            {
                this.Invoke((MethodInvoker)delegate()
                {
                    try
                    {
                        System.Windows.Forms.Application.DoEvents();
                        LoadViews();
                        System.Windows.Forms.Application.DoEvents();

                        sqlEventSource.GetMachineLogList(Properties.Settings.Default.ViewDisabledLogs);
                        sqlEventSource.GetSourceList();
                        sqlEventSource.GetEventIDList();

                        System.Threading.Thread.Sleep(800);
                        initializing = false;
                       
                        //RefreshList();
                        timerViewSelect.Enabled = false;
                        LoadInitialStartUpView();
                        lvwEvents.Focus();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                );
            }
            ).Start();  
        }
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.WindowState == FormWindowState.Normal)
            {
                Properties.Settings.Default.MainFormLocation = this.Location;
                Properties.Settings.Default.MainFormSize = this.Size;
            }
            Properties.Settings.Default.StayUpToDateRefresh = chkStayUpToDate.Checked;
            Properties.Settings.Default.ShowAllMachineLogs = sqlEventSource.ShowAllMachineLogs;
            Properties.Settings.Default.MachineLogFilter = new System.Collections.Specialized.StringCollection();
            foreach (MachineLogEntry mle in sqlEventSource.MachineLogFilters)
            {
                Properties.Settings.Default.MachineLogFilter.Add(mle.Machine + "\\" + mle.LogName);
            }
            Properties.Settings.Default.TextSearchHistoryList = new System.Collections.Specialized.StringCollection();
            foreach (string textSearch in txtTextSearch.AutoCompleteCustomSource)
            {
                Properties.Settings.Default.TextSearchHistoryList.Add(textSearch);
            }
            if (cboMaxEntriesFilter.Text != "All")
                Properties.Settings.Default.TopViewCount = int.Parse(cboMaxEntriesFilter.Text);
            Properties.Settings.Default.ViewAutoRefresh = autoRefreshVisibleToolStripMenuItem1.Checked;
            Properties.Settings.Default.LastTextFilter = txtTextSearch.Text;
            Properties.Settings.Default.FullTextSearchOnFind = searchFullTextToolStripMenuItem.Checked;

            try //saving current filter settings
            {
                EventLogView currentView = new EventLogView();
                currentView.Name = "";
                currentView.MachineLogs = sqlEventSource.MachineLogFilters;
                currentView.ShowAllLogs = sqlEventSource.ShowAllMachineLogs;
                currentView.EventIds = sqlEventSource.EventIdsVisible;
                currentView.ShowAllEventIDs = sqlEventSource.ViewAllEventIDs;
                currentView.Sources = sqlEventSource.SourceFilters;
                currentView.ShowAllSources = sqlEventSource.ShowAllSources;
                currentView.EventLogEntryType = (int)sqlEventSource.EventLogEntryType;
                currentView.FilterText = sqlEventSource.MessageFilter;
                currentView.Name = "Previous Session";

                string serialized = Serializer.SerializeXML(currentView);
                string defaultViewPath = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DefaultInitialView.elvw");
                System.IO.File.WriteAllText(defaultViewPath, serialized);
            }
            catch { }

            Properties.Settings.Default.Save();
        }
        private void MainForm_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F5)
            {
                toolStripButtonRefresh_Click(null, null);
            }
            else if (e.KeyCode == Keys.F4)
            {
                cboViews.Focus();
            }
            else if (e.Control && e.KeyCode == Keys.N)
                newWindowToolStripMenuItem_Click(null, null);
        }
        private void MainForm_ResizeEnd(object sender, EventArgs e)
        {
            cboViews.Refresh();
        }
        #endregion

        #region Main toolbar events
        private void toolStripButtonRefresh_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                Cursor.Current = Cursors.WaitCursor;
                toDateTimeChooser.SelectedDateTime = DateTime.Now.AddMinutes(1);
                RefreshEventTimer.Enabled = false;
                RefreshEventTimer.Enabled = true;
            }
        }
        #endregion

        #region Menu events
        private void newWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(Application.ExecutablePath);
        }
        private void exportSelectedEntriesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ExportEntries(false);
        }
        private void toolStripMenuItemExportAll_Click(object sender, EventArgs e)
        {
            ExportEntries(true);
        }
        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvwi in lvwEvents.Items)
            {
                lvwi.Selected = true;
            }
        }
        private void findToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InputBox inputBox = new InputBox();
            inputBox.Title = "Find";
            inputBox.Prompt = "Specify text to search for:";
            inputBox.SelectedValue = searchStr;
            inputBox.FullTextSearchCaption = "Search message details";
            inputBox.FullTextSearch = searchFullTextToolStripMenuItem.Checked;
            if (inputBox.ShowInputBox() == System.Windows.Forms.DialogResult.OK)
            {
                searchStr = inputBox.SelectedValue;
                searchFullTextToolStripMenuItem.Checked = inputBox.FullTextSearch;
                if (searchStr.Length > 0)
                    SearchForMessageText(searchStr);
            }
        }
        private void findAgainToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SearchForMessageText(searchStr);
        }
        private void autoRefreshVisibleToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            autoRefreshVisibleToolStripMenuItem1.Checked = !autoRefreshVisibleToolStripMenuItem1.Checked;
            toolStripButtonAutoUpdate.Visible = autoRefreshVisibleToolStripMenuItem1.Checked;
            toolStripLabelRate.Visible = autoRefreshVisibleToolStripMenuItem1.Checked;
            rateToolStripComboBox.Visible = autoRefreshVisibleToolStripMenuItem1.Checked;
        }
        private void viewHideDetailsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer1.Panel2Collapsed = !splitContainer1.Panel2Collapsed;
            //cmdToggleHideDetails.Text = splitContainer1.Panel2Collapsed ? "ttt" : "uuu";
            if (splitContainer1.SplitterDistance > splitContainer1.Height - 200)
                splitContainer1.SplitterDistance = splitContainer1.Height - 200;
            if (lvwEvents.SelectedItems.Count > 0)
                lvwEvents.SelectedItems[0].EnsureVisible();
            viewHideDetailsToolStripMenuItem1.Checked = !splitContainer1.Panel2Collapsed;
            if (splitContainer1.Panel2Collapsed)
                cmdToggleHideDetails2.Image = global::EventScavenger.Properties.Resources.UpBtn;
            else
                cmdToggleHideDetails2.Image = global::EventScavenger.Properties.Resources.DownBtn;
        }
        private void viewHideProfileListToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainerProfilesList.Panel1Collapsed = !splitContainerProfilesList.Panel1Collapsed;
            cmdToggleHideProfiles.Text = splitContainerProfilesList.Panel1Collapsed ? "444" : "333";
        }
        private void highlightsToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
        {
            highlightsToolStripMenuItem1.Checked = !highlightsToolStripMenuItem1.Checked;
            toolStripHighLights.Visible = highlightsToolStripMenuItem1.Checked;
        }
        private void analizeEventsToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            eventAnalizer = new EventAnalizer();
            eventAnalizer.UpdateAnalizerData += new UpdateAnalizerDataDelegate(eventAnalizer_UpdateAnalizerData);
            eventAnalizer.ShowAnylizer(list.ToArray());
        }
        private void countPerPeriodToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            using (CountsPerPeriod countsPerPeriod = new CountsPerPeriod())
            {
                countsPerPeriod.ShowCountsPerPeriod(sqlEventSource);
            }
        }
        private void connectionSettingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool newServer;
            using (SetConnection setConnection = new SetConnection())
            {
                if (setConnection.ShowSetConnection() == DialogResult.OK)
                {
                    newServer = !((sqlEventSource.Server == Properties.Settings.Default.SQLServer) && (sqlEventSource.Database == Properties.Settings.Default.Database));
                    sqlEventSource.Server = Properties.Settings.Default.SQLServer;
                    sqlEventSource.Database = Properties.Settings.Default.Database;
                    sqlEventSource.UserName = Properties.Settings.Default.UserName;
                    sqlEventSource.Password = Properties.Settings.Default.Password;
                    sqlEventSource.CommandTimeout = Properties.Settings.Default.SQLCMDTimeOut;
                    sqlEventSource.SetConnection();
                    SetAppTitle();

                    if (newServer)
                    {
                        sqlEventSource.AvailableMachineLog = new List<MachineLogEntry>();
                        sqlEventSource.MachineLogFilters = new List<MachineLogEntry>();
                        sqlEventSource.ShowAllMachineLogs = true;

                        sqlEventSource.AvailableSources = new List<string>();
                        sqlEventSource.SourceFilters = new List<string>();
                        sqlEventSource.ShowAllSources = true;

                        sqlEventSource.EventIdsVisible = new List<int>();
                        sqlEventSource.AvailableEventIDs = new List<int>();
                        sqlEventSource.ViewAllEventIDs = true;

                        DisplaySelectedMLEs();

                        DisplaySelectedEventIDs();

                        DisplaySelectedSources();
                    }

                    RefreshList();
                }
            }
        }
        private void viewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (ViewManager viewFilterManager = new ViewManager())
            {
                if (viewFilterManager.Show(sqlEventSource) == DialogResult.OK)
                {
                    LoadViews();
                    foreach (ListViewItem lvi in lvwProfiles.Items)
                    {
                        lvi.Selected = (lvi.Text == viewFilterManager.SelectedView.Name);
                    }
                }
            }
        }
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (AboutWindow aboutWindow = new AboutWindow())
            {
                aboutWindow.ShowDialog();
            }
        }
        #endregion

        #region Main Events ListView events
        private void lvwEvents_SelectedIndexChanged(object sender, EventArgs e)
        {
            timerSelectItem.Enabled = false;
            exportSelectedEntriesToolStripMenuItem1.Enabled = (lvwEvents.SelectedItems.Count > 0);
            if (lvwEvents.SelectedItems.Count > 0)
                toolStripStatusLabel2.Text = lvwEvents.SelectedItems.Count.ToString() + " item(s) selected";
            else
                toolStripStatusLabel2.Text = "";
            timerSelectItem.Enabled = true;
        }
        private void lvwEvents_Resize(object sender, EventArgs e)
        {
            //Give all other control updating time to finish
            new System.Threading.Thread(delegate()
            {
                System.Threading.Thread.Sleep(50);
                if (this.Visible && this.WindowState != FormWindowState.Minimized)
                {
                    this.Invoke((MethodInvoker)delegate()
                    {
                        try
                        {
                            int leftPos = lvwEvents.Columns[0].Width + lvwEvents.Columns[1].Width + lvwEvents.Columns[2].Width +
                                    lvwEvents.Columns[3].Width + lvwEvents.Columns[4].Width + lvwEvents.Columns[5].Width + lvwEvents.Columns[6].Width;
                            lvwEvents.Columns[7].Width = lvwEvents.ClientSize.Width - leftPos;
                        }
                        catch { }
                    }
                        );
                }
            }
             ).Start();
        }
        private void lvwEvents_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                propertiesToolStripMenuItem_Click(sender, e);
            else if (e.KeyCode == Keys.Left)
            {
                if (Properties.Settings.Default.ItemsGroupBy > 0)
                {
                    if (lvwEvents.SelectedItems.Count > 0 && lvwEvents.SelectedItems[0].Group != null)
                    {
                        lvwEvents.SetGroupState(lvwEvents.SelectedItems[0].Group, ListViewGroupState.Collapsible | ListViewGroupState.Collapsed);
                    }                    
                }
            }
            else if (e.KeyCode == Keys.Right)
            {
                if (Properties.Settings.Default.ItemsGroupBy > 0)
                {
                    if (lvwEvents.SelectedItems.Count > 0 && lvwEvents.SelectedItems[0].Group != null)
                    {
                        ListViewItem lvi = lvwEvents.SelectedItems[0];
                        lvwEvents.SetGroupState(lvwEvents.SelectedItems[0].Group, ListViewGroupState.Collapsible | ListViewGroupState.Normal);
                        lvwEvents.SelectedItems.Clear();
                        lvi.Selected = true;
                        lvi.EnsureVisible();
                    }
                }
            }
        }
        #endregion

        #region Event list context menu events
        private void filterBySelectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool found;
            sqlEventSource.MachineLogFilters = new List<MachineLogEntry>();
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                found = false;
                foreach (MachineLogEntry ml in sqlEventSource.MachineLogFilters)
                {
                    if ((((EventEntry)lvi.Tag).MachineName == ml.Machine) && (((EventEntry)lvi.Tag).LogName == ml.LogName))
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    sqlEventSource.MachineLogFilters.Add(new MachineLogEntry(((EventEntry)lvi.Tag).MachineName, ((EventEntry)lvi.Tag).LogName));
                }
            }
            sqlEventSource.ShowAllMachineLogs = false;
            DisplaySelectedMLEs();
            RefreshList();
        }
        private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwEvents.SelectedItems.Count > 0)
            {
                try
                {
                    eventLogDetailView.ShowEventProperties((EventEntry)lvwEvents.SelectedItems[0].Tag, list);
                }
                catch (ObjectDisposedException)
                {
                    eventLogDetailView.NavigateToItem -= new EventLogDetailView.NavigateToItemDelegate(eventLogDetailView_NavigateToItem);
                    eventLogDetailView = new EventLogDetailView();
                    eventLogDetailView.NavigateToItem += new EventLogDetailView.NavigateToItemDelegate(eventLogDetailView_NavigateToItem);
                    eventLogDetailView.ShowEventProperties((EventEntry)lvwEvents.SelectedItems[0].Tag, list);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        private void excludeSelectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (sqlEventSource.MachineLogFilters.Count == 0)
            {
                sqlEventSource.MachineLogFilters = sqlEventSource.GetMachineLogList(Properties.Settings.Default.ViewDisabledLogs);
            }
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                for (int i = 0; i < sqlEventSource.MachineLogFilters.Count; i++)
                {
                    MachineLogEntry ml = sqlEventSource.MachineLogFilters[i];
                    if ((((EventEntry)lvi.Tag).MachineName == ml.Machine) && (((EventEntry)lvi.Tag).LogName == ml.LogName))
                    {
                        sqlEventSource.MachineLogFilters.Remove(ml);
                        break;
                    }
                }
            }
            sqlEventSource.ShowAllMachineLogs = false;
            DisplaySelectedMLEs();
            RefreshList();
        }
        private void clearAllToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            sqlEventSource.MachineLogFilters = new List<MachineLogEntry>();
            sqlEventSource.ShowAllMachineLogs = true;
            DisplaySelectedMLEs();
            RefreshList();
        }        
        private void toolStripMenuItemFilterByEventID_Click(object sender, EventArgs e)
        {
            sqlEventSource.EventIdsVisible = new List<int>();
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                if (!sqlEventSource.EventIdsVisible.Contains(((EventEntry)lvi.Tag).EventID))
                    sqlEventSource.EventIdsVisible.Add(((EventEntry)lvi.Tag).EventID);
            }
            sqlEventSource.ViewAllEventIDs = false;
            DisplaySelectedEventIDs();
            RefreshList();
        }
        private void toolStripMenuItemExcludeID_Click(object sender, EventArgs e)
        {
            if (sqlEventSource.EventIdsVisible.Count == 0)
            {
                sqlEventSource.EventIdsVisible = sqlEventSource.GetEventIDList();
            }
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                sqlEventSource.EventIdsVisible.Remove(((EventEntry)lvi.Tag).EventID);
            }
            sqlEventSource.ViewAllEventIDs = false;
            DisplaySelectedEventIDs();
            RefreshList();
        }
        private void clearAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sqlEventSource.ViewAllEventIDs = true;
            sqlEventSource.EventIdsVisible = new List<int>();
            DisplaySelectedEventIDs();
            RefreshList();
        }
        private void filterSourceBySelectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sqlEventSource.SourceFilters = new List<string>();
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                if (!sqlEventSource.SourceFilters.Contains(((EventEntry)lvi.Tag).SourceName))
                    sqlEventSource.SourceFilters.Add(((EventEntry)lvi.Tag).SourceName);
            }
            sqlEventSource.ShowAllSources = false;
            DisplaySelectedSources();
            RefreshList();
        }
        private void toolStripMenuItemExcludeSource_Click(object sender, EventArgs e)
        {
            if (sqlEventSource.SourceFilters.Count == 0)
            {
                sqlEventSource.SourceFilters = sqlEventSource.GetSourceList();
            }
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                sqlEventSource.SourceFilters.Remove(((EventEntry)lvi.Tag).SourceName);
            }
            sqlEventSource.ShowAllSources = false;
            DisplaySelectedSources();
            RefreshList();
        }
        private void clearAllSourceFiltersToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            sqlEventSource.SourceFilters = new List<string>();
            sqlEventSource.ShowAllSources = true;
            DisplaySelectedSources();
            RefreshList();
        }
        private void applyExistingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ViewManager viewFilterManager = new ViewManager();
            if (viewFilterManager.Show(sqlEventSource) == DialogResult.OK)
            {

                foreach (ListViewItem lvi in lvwProfiles.Items)
                {
                    lvi.Selected = (lvi.Text == viewFilterManager.SelectedView.Name);
                }
                LoadViews();
            }
        }
        private void saveCurrentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            EventLogView newView = new EventLogView();
            newView.MachineLogs = sqlEventSource.MachineLogFilters;
            newView.ShowAllLogs = sqlEventSource.ShowAllMachineLogs;
            newView.EventIds = sqlEventSource.EventIdsVisible;
            newView.ShowAllEventIDs = sqlEventSource.ViewAllEventIDs;
            newView.Sources = sqlEventSource.SourceFilters;
            newView.ShowAllSources = sqlEventSource.ShowAllSources;
            newView.EventLogEntryType = (int)sqlEventSource.EventLogEntryType;
            newView.FilterText = sqlEventSource.MessageFilter;
            ViewEditor viewEditor = new ViewEditor();
            viewEditor.SelectedView = newView;
            if (viewEditor.Show(sqlEventSource) == DialogResult.OK)
            {
                newView = viewEditor.SelectedView;
                if (Properties.Settings.Default.PredefineViewPaths == null)
                    Properties.Settings.Default.PredefineViewPaths = new System.Collections.Specialized.StringCollection();
                Properties.Settings.Default.PredefineViewPaths.Add(newView.ViewPath);

                initializing = true;
                sqlEventSource.MachineLogFilters = newView.MachineLogs;
                sqlEventSource.ShowAllMachineLogs = newView.ShowAllLogs;
                DisplaySelectedMLEs();
                sqlEventSource.EventIdsVisible = newView.EventIds;
                sqlEventSource.ViewAllEventIDs = newView.ShowAllEventIDs;
                DisplaySelectedEventIDs();
                sqlEventSource.SourceFilters = newView.Sources;
                sqlEventSource.ShowAllSources = newView.ShowAllSources;
                DisplaySelectedSources();
                initializing = false;
                lvwProfiles.SelectedItems.Clear();
                LoadViews();
            }
        }
        private void thisItemToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                if (lvi.BackColor == highLightColor)
                    lvi.BackColor = SystemColors.Window;
                else
                    lvi.BackColor = highLightColor;
            }
        }
        private void toolStripButtonHighLightMachineLog_Click(object sender, EventArgs e)
        {
            bool found;
            if (highLightMachineLogs == null || highLightMachineLogs.Count == 0)
                highLightMachineLogs = new List<MachineLogEntry>();
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                found = false;
                foreach (MachineLogEntry ml in highLightMachineLogs)
                {
                    if ((((EventEntry)lvi.Tag).MachineName == ml.Machine) && (((EventEntry)lvi.Tag).LogName == ml.LogName))
                    {
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    highLightMachineLogs.Add(new MachineLogEntry(((EventEntry)lvi.Tag).MachineName, ((EventEntry)lvi.Tag).LogName));
                }
            }
            ApplyHighLights();
        }
        private void allEventIDsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (highLightIds == null)
                highLightIds = new List<int>();
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                if (!highLightIds.Contains(((EventEntry)lvi.Tag).EventID))
                    highLightIds.Add(((EventEntry)lvi.Tag).EventID);
            }
            ApplyHighLights();
        }
        private void allEventSourcesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (highLightSources == null)
                highLightSources = new List<string>();
            foreach (ListViewItem lvi in lvwEvents.SelectedItems)
            {
                if (!highLightSources.Contains(((EventEntry)lvi.Tag).SourceName))
                    highLightSources.Add(((EventEntry)lvi.Tag).SourceName);
            }
            ApplyHighLights();
        }
        private void clearAllToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            highLightIds = new List<int>();
            highLightSources = new List<string>();
            highLightMachineLogs = new List<MachineLogEntry>();
            ApplyHighLights();
        }

        #endregion

        #region Views listview events
        private void lvwProfiles_Resize(object sender, EventArgs e)
        {
            columnHeaderProfilesView.Width = lvwProfiles.ClientSize.Width - 1;
        }
        private void lvwProfiles_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!initializing)
            {
                timerViewSelect.Enabled = false;
                timerViewSelect.Enabled = true;
            }
        }
        private void lvwProfiles_DragDrop(object sender, DragEventArgs e)
        {
            Properties.Settings.Default.PredefineViewPaths = new System.Collections.Specialized.StringCollection();
            foreach (ListViewItem lvi in lvwProfiles.Items)
            {
                if (lvi.Text != "All/No filter")
                {
                    EventLogView eventLogView = (EventLogView)lvi.Tag;
                    Properties.Settings.Default.PredefineViewPaths.Add(eventLogView.ViewPath);
                }
            }
        }
        private void lvwProfiles_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                applyFilterProfileToolStripMenuItem_Click(sender, e);
            }
        }
        private void timerViewSelect_Tick(object sender, EventArgs e)
        {
            timerViewSelect.Enabled = false;
            ApplySelectedProfile();
        }
        private void ApplySelectedProfile()
        {
            EventLogView selectedView;
            if (cboViews.SelectedIndex > 0)
            {
                selectedView = (EventLogView)cboViews.SelectedItem;                
            }
            else
            {
                selectedView = new EventLogView();
            }
            ApplyEventLogView(selectedView);
            lvwEvents.Focus();
        }
        private void cboViews_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!initializing)
            {
                timerViewSelect.Enabled = false;
                timerViewSelect.Enabled = true;
            }
        }
        private void cmdShowViews_Click(object sender, EventArgs e)
        {
            using (ViewManager viewFilterManager = new ViewManager())
            {
                if (viewFilterManager.Show(sqlEventSource) == DialogResult.OK)
                {
                    LoadViews();
                    foreach (object item in cboViews.Items)
                    {
                        if (item is EventLogView)
                        {
                            if (((EventLogView)item).Name == viewFilterManager.SelectedView.Name)
                            {
                                cboViews.SelectedItem = item;
                                break;
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region Filter control events
        private void cmdMaxEntries_Click(object sender, EventArgs e)
        {
            cboMaxEntriesFilter.Focus();
        }
        private void cmdTypeFilter_Click(object sender, EventArgs e)
        {
            cboTypeFilter.Focus();
        }
        private void cmdFilterByText_Click(object sender, EventArgs e)
        {
            txtTextSearch.Focus();
        }
        private void cmdLogs_Click(object sender, EventArgs e)
        {
            MachineLogFilter machineLogFilter = new MachineLogFilter();
            machineLogFilter.AllEnabled = sqlEventSource.ShowAllMachineLogs;
            machineLogFilter.SelectedMachineLogs = sqlEventSource.MachineLogFilters;
            if (machineLogFilter.Show(sqlEventSource) == DialogResult.OK)
            {
                sqlEventSource.ShowAllMachineLogs = machineLogFilter.AllEnabled;
                sqlEventSource.MachineLogFilters = machineLogFilter.SelectedMachineLogs;
                DisplaySelectedMLEs();
                CheckStayUpToDate();
                RefreshList();
            }
        }
        private void cmdSources_Click(object sender, EventArgs e)
        {
            EventSourceFilter eventSourceFilter = new EventSourceFilter();
            eventSourceFilter.AllEnabled = sqlEventSource.ShowAllSources;
            eventSourceFilter.SelectedSources = sqlEventSource.SourceFilters;
            if (eventSourceFilter.Show(sqlEventSource) == DialogResult.OK)
            {
                sqlEventSource.ShowAllSources = eventSourceFilter.AllEnabled;
                sqlEventSource.SourceFilters = eventSourceFilter.SelectedSources;
                DisplaySelectedSources();
                CheckStayUpToDate();
                RefreshList();
            }
        }
        private void cmdIDs_Click(object sender, EventArgs e)
        {
            EventIDFilter eventIDFilter = new EventIDFilter();
            eventIDFilter.AllEnabled = sqlEventSource.ViewAllEventIDs;
            eventIDFilter.SelectedIds = sqlEventSource.EventIdsVisible;
            if (eventIDFilter.Show(sqlEventSource) == DialogResult.OK)
            {
                sqlEventSource.ViewAllEventIDs = eventIDFilter.AllEnabled;
                sqlEventSource.EventIdsVisible = eventIDFilter.SelectedIds;
                DisplaySelectedEventIDs();
                CheckStayUpToDate();
                RefreshList();
            }
        }
        private void cmdFromDate_Click(object sender, EventArgs e)
        {
            fromDateTimeChooser.Focus();
        }
        private void cmdUntilDate_Click(object sender, EventArgs e)
        {
            toDateTimeChooser.Focus();
        }
        private void chkStayUpToDate_CheckedChanged(object sender, EventArgs e)
        {
            ShowCurrentFilterSummary();
        }
        #endregion

        #region Refreshing
        private void LoadInitialStartUpView()
        {
            try
            {
                initializing = true;
                if (!(initialViewOnStartUp.Length > 0 && System.IO.File.Exists(initialViewOnStartUp)))
                {
                    initialViewOnStartUp = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DefaultInitialView.elvw");
                    if (!System.IO.File.Exists(initialViewOnStartUp)) //no default view exists
                    {
                        sqlEventSource.ShowAllMachineLogs = true;
                        sqlEventSource.ShowAllSources = true;
                        sqlEventSource.ViewAllEventIDs = true;
                        sqlEventSource.MessageFilter = "";
                        sqlEventSource.EventLogEntryType = EventLogEntryTypes.All;
                        RefreshList();
                        return;
                    }                    
                }
                EventLogView eventLogView = EventLogView.LoadViewFromFile(initialViewOnStartUp);
                eventLogView.Name = "Previous Session";
                cboViews.Text = eventLogView.Name;
               
                ApplyEventLogView(eventLogView);
                initializing = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Loading initial view", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private bool TestConnection()
        {
            bool success = false;
            try
            {
                sqlEventSource.TestConnection();
                success = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Connection error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return success;
        }
        private void CheckStayUpToDate()
        {
            if (chkStayUpToDate.Checked)
                toDateTimeChooser.SelectedDateTime = DateTime.Now.AddMinutes(1);
        }
        private void RefreshList()
        {
            string message;
            EventEntry selectedEntry = null;
            ListViewItem selectedListViewItem = null;
            int totalCount = 0;
            int totalWarnings = 0;
            int totalErrors = 0;

            if (initializing)
                return;
            if (!ApplyFilters())
                return;

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                initializing = true;
                refreshCount++;

                if (txtTextSearch.Text.Length > 2)
                {
                    if (!txtTextSearch.AutoCompleteCustomSource.Contains(txtTextSearch.Text))
                    {
                        txtTextSearch.AutoCompleteCustomSource.Add(txtTextSearch.Text);
                    }
                }
                if (lvwEvents.SelectedItems.Count > 0)
                {
                    selectedEntry = (EventEntry)lvwEvents.SelectedItems[0].Tag;
                }

                //showing loading...
                lvwEvents.BeginUpdate();
                lvwEvents.Items.Clear();
                lvwEvents.Groups.Clear();
                lvwEvents.Items.Add(new ListViewItem("Loading..."));
                lvwEvents.EndUpdate();
                Application.DoEvents();

                list = sqlEventSource.GetEntries(); //Load new entries 
                PreOrderListForGrouping();

                List<ListViewItem> listEntries = new List<ListViewItem>(); //temporary list to hold entries
                lvwEvents.BeginUpdate();
                lvwEvents.Items.Clear();
                lvwEvents.ShowGroups = !groupByNoneToolStripMenuItem.Checked;
                lvwEvents.GroupDescription = GetListViewGroupDescription();
                Cursor.Current = Cursors.WaitCursor;
                foreach (EventEntry entry in list)
                {
                    totalCount++;
                    ListViewItem lvi = new ListViewItem(entry.MachineName);
                    if (entry.EventTypeName.Substring(0, 1) == "W")
                    {
                        lvi.ImageIndex = 4;
                        totalWarnings++;
                    }
                    else if ((entry.EventTypeName.Substring(0, 1) == "E") || (entry.EventTypeName.Substring(0, 1) == "F"))
                    {
                        lvi.ImageIndex = 3;
                        totalErrors++;
                    }
                    else
                        lvi.ImageIndex = 2;

                    lvi.SubItems.Add(entry.LogName);
                    lvi.SubItems.Add(entry.EventTypeName);
                    lvi.SubItems.Add(entry.TimeGenerated.ToShortDateString());
                    lvi.SubItems.Add(entry.TimeGenerated.ToString("HH:mm:ss"));
                    lvi.SubItems.Add(entry.SourceName);
                    lvi.SubItems.Add(entry.EventID.ToString());
                    message = entry.Message;
                    if (message.Length > 80)
                        message = message.Substring(0, 80);
                    message = message.Replace("\r\n", "|");
                    lvi.SubItems.Add(message);
                    lvi.Tag = entry;
                    if ((selectedEntry != null) && (selectedEntry.Equal(entry)))
                    {
                        selectedListViewItem = lvi;
                    }
                    lvi.Group = GetListViewGroupBySelectedGroup(lvi);
                    listEntries.Add(lvi);
                }
                lvwEvents.Items.AddRange(listEntries.ToArray());
                if (selectedListViewItem != null)
                {
                    selectedListViewItem.Selected = true;
                    selectedListViewItem.EnsureVisible();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                lvwEvents.EndUpdate();
                ApplyHighLights();

                lblDetailSummary.Text = string.Format("[Details - F8] {0} item(s), {1} warning(s), {2} error(s)",
                    totalCount, totalWarnings, totalErrors);
                //toolStripStatusLabel1.Text = string.Format("{0} item(s), {1} warning(s), {2} error(s)",
                //    totalCount, totalWarnings, totalErrors);

                if (lvwEvents.ShowGroups)
                {
                    lvwEvents.BeginUpdate();
                    foreach (ListViewGroup lvg in lvwEvents.Groups)
                    {
                        lvwEvents.SetGroupFooter(lvg, string.Format("  {0} item(s)", lvg.Items.Count));
                    }
                    //bug in Footer code - if list is big then painting gets screwed up
                    //Fix is to trigger a redraw/refresh of the control
                    lvwEvents.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Normal);
                    lvwEvents.EndUpdate();
                }
                Cursor.Current = Cursors.Default;
                initializing = false;
            }
            try
            {
                toolStripStatusLabelTotalRows.Text = string.Format("Total: {0} row(s)", sqlEventSource.TestConnection());
                ShowCurrentFilterSummary();
            }
            catch { }
        }
        private void PreOrderListForGrouping()
        {
            if (!groupByNoneToolStripMenuItem.Checked &&
                //Data is retrieved in descending order from database already
                !groupByDateToolStripMenuItem.Checked && 
                !groupByHourToolStripMenuItem.Checked &&
                !groupByMonthToolStripMenuItem.Checked)
            {
                list.Sort(
                    delegate(EventEntry e1, EventEntry e2)
                    {
                        int compared = 0;
                        if (groupByMachineToolStripMenuItem.Checked)
                        {
                            compared = e1.MachineName.CompareTo(e2.MachineName);                            
                        }
                        else if (groupByLogToolStripMenuItem.Checked)
                        {
                            compared = e1.LogName.CompareTo(e2.LogName);
                        }
                        else if (groupByTypeToolStripMenuItem.Checked)
                        {
                            compared = e1.EventTypeName.CompareTo(e2.EventTypeName);
                        }
                        else if (groupBySourceToolStripMenuItem.Checked)
                        {
                            compared = e1.SourceName.CompareTo(e2.SourceName);
                        }
                        else if (groupByEventIDToolStripMenuItem.Checked)
                        {
                            compared = e1.EventID.CompareTo(e2.EventID);
                        }
                        else if (groupBySummaryToolStripMenuItem.Checked)
                        {
                            int maxlength = 50;
                            string s1 = e1.Message.Length > maxlength ? e1.Message.Substring(0, maxlength) : e1.Message;
                            string s2 = e2.Message.Length > maxlength ? e2.Message.Substring(0, maxlength) : e2.Message;
                            compared = s1.CompareTo(s2);
                        }
                        if (compared == 0)
                            return -e1.TimeGenerated.CompareTo(e2.TimeGenerated);
                        else
                            return compared;
                    }
                );
            }
        }
        private bool ApplyFilters()
        {
            bool success = true;

            if (cboMaxEntriesFilter.Text != "All")
                sqlEventSource.MaxCount = int.Parse(cboMaxEntriesFilter.Text);
            else
            {
                if (MessageBox.Show("Are you sure you want to select [top] all entries?", "All", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    return false;
                toolStripButtonAutoUpdate.Image = Properties.Resources.Stop2;
                autoUpdate = false;
                eventTimer.Enabled = false;
                sqlEventSource.MaxCount = 0;
            }
            sqlEventSource.UntilDate = toDateTimeChooser.SelectedDateTime;
            sqlEventSource.FromDate = fromDateTimeChooser.SelectedDateTime;
            sqlEventSource.EventLogEntryType = (EventLogEntryTypes)cboTypeFilter.SelectedIndex;
            sqlEventSource.MessageFilter = txtTextSearch.Text;

            sqlEventSource.ViewDisabledMachineLogs = Properties.Settings.Default.ViewDisabledLogs;

            return success;
        }
        private void ApplyHighLights()
        {
            foreach (ListViewItem lvi in lvwEvents.Items)
            {
                if (highLightIds.Contains(int.Parse(lvi.SubItems[6].Text)))
                {
                    lvi.BackColor = highLightColor;
                }
                else if (highLightSources.Contains(lvi.SubItems[5].Text))
                    lvi.BackColor = highLightColor;
                else
                {
                    lvi.BackColor = SystemColors.Window;
                    foreach (MachineLogEntry mle in highLightMachineLogs)
                    {
                        if (lvi.Text == mle.Machine && lvi.SubItems[1].Text == mle.LogName)
                        {
                            lvi.BackColor = highLightColor;
                        }
                    }
                }
            }
        }
        private void RefreshEventTimer_Tick(object sender, EventArgs e)
        {
            RefreshEventTimer.Enabled = false;
            if (TestConnection())
            {
                RefreshList();
            }
            else
                MessageBox.Show(sqlEventSource.LastError, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

        }
        private void eventTimer_Tick(object sender, EventArgs e)
        {
            if (autoUpdate)
            {
                toDateTimeChooser.SelectedDateTime = DateTime.Now;
            }
            if (TestConnection())
            {
                RefreshList();
            }
            else
            {
                autoUpdate = false;
                toolStripButtonAutoUpdate.Image = Properties.Resources.Stop2;
                eventTimer.Enabled = false;
                MessageBox.Show(sqlEventSource.LastError, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void cmdApplyQuickFilter_Click(object sender, EventArgs e)
        {
            RefreshList();
            lvwEvents.Focus();
        }
        private void toolStripButtonAutoUpdate_Click(object sender, EventArgs e)
        {
            autoUpdate = !autoUpdate;
            if (autoUpdate)
                toolStripButtonAutoUpdate.Image = Properties.Resources.PLAY;
            else
                toolStripButtonAutoUpdate.Image = Properties.Resources.Stop2;
            eventTimer.Interval = int.Parse(rateToolStripComboBox.Text) * 1000;
            eventTimer.Enabled = autoUpdate;
            fromDateTimeChooser.Enabled = !autoUpdate;
            toDateTimeChooser.Enabled = !autoUpdate;
        }
        private void rateToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            eventTimer.Interval = int.Parse(rateToolStripComboBox.Text) * 1000;
        }
        #endregion

        #region Navigation
        //When the user clicks up or down on the detail window.
        public void eventLogDetailView_NavigateToItem(EventEntry displayItem)
        {
            for (int i = 0; i < lvwEvents.Items.Count; i++)
            {
                if (displayItem.Equals((EventEntry)lvwEvents.Items[i].Tag))
                {

                    if (lvwEvents.SelectedItems != null)
                        lvwEvents.SelectedItems.Clear();
                    lvwEvents.Items[i].Selected = true;
                    lvwEvents.Items[i].EnsureVisible();
                    break;
                }
            }
        }
        private void DisplaySelectedItemDetails(int maxSelection)
        {
            string oldStatusText = lblDetailSummary.Text; // toolStripStatusLabel1.Text;
            RTFBuilder rtfBuilder = new RTFBuilder();

            //avoid cursor flickering when only a few items are selected
            if (lvwEvents.SelectedItems.Count > MAXPREVIEWDISPLAYCOUNT)
                Cursor.Current = Cursors.WaitCursor;
            //have to limit the maximum number of selected items
            foreach (ListViewItem lvi in (from ListViewItem l in lvwEvents.SelectedItems
                                          select l).Take(maxSelection))
            {
                EventEntry entry = (EventEntry)lvi.Tag;

                rtfBuilder.FontStyle(FontStyle.Bold).Append("Date time: ").AppendLine(entry.TimeGenerated.ToShortDateString() + " " + entry.TimeGenerated.ToShortTimeString());
                rtfBuilder.FontStyle(FontStyle.Bold).Append("Type: ").AppendLine(entry.EventTypeName);
                rtfBuilder.FontStyle(FontStyle.Bold).Append("Machine\\Log: ").AppendLine(entry.MachineName + "\\" + entry.LogName);
                rtfBuilder.FontStyle(FontStyle.Bold).Append("Source: ").AppendLine(entry.SourceName);
                rtfBuilder.FontStyle(FontStyle.Bold).Append("Event ID: ").AppendLine(entry.EventID.ToString());
                rtfBuilder.FontStyle(FontStyle.Bold).Append("Repeats: ").AppendLine(entry.Repeat.ToString());
                rtfBuilder.FontStyle(FontStyle.Bold).Append("User: ").AppendLine(entry.UserName);
                rtfBuilder.FontStyle(FontStyle.Bold).Append("Message:");
                rtfBuilder.AppendPara().LineIndent(500).AppendLine(entry.Message);
                rtfBuilder.FontStyle(FontStyle.Underline).AppendLine(new String(' ', 250));
                rtfBuilder.AppendLine();
            }
            if (lvwEvents.SelectedItems.Count > maxSelection)
            {
                rtfBuilder.FontStyle(FontStyle.Bold).AppendLine(string.Format("Only first {0} entries shown... Use 'Show details for all selected items' to display all", maxSelection));
            }
            else if (lvwEvents.SelectedItems.Count == 0)
                rtfBuilder.FontStyle(FontStyle.Bold).AppendLine("No entries selected");
            else
            {
                rtfBuilder.FontStyle(FontStyle.Bold).AppendLine(string.Format("{0} entry(s)", lvwEvents.SelectedItems.Count));
            }
            rtxtEntryDetail.Rtf = rtfBuilder.ToString();
            rtxtEntryDetail.SelectionStart = 0;
            rtxtEntryDetail.SelectionLength = 0;
            rtxtEntryDetail.ScrollToCaret();
            Cursor.Current = Cursors.Default;
            lblDetailSummary.Text = oldStatusText;
        }
        private void timerSelectItem_Tick(object sender, EventArgs e)
        {
            timerSelectItem.Enabled = false;
            DisplaySelectedItemDetails(MAXPREVIEWDISPLAYCOUNT);
        }
        #endregion

        #region Views
        private void cmdFilterPanelSizeToggle2_Click(object sender, EventArgs e)
        {
            if (panFilters.Height == filterExpandedSize)
            {
                panFilters.Height = filterCollapsedSize;
                panFilterDetails.Visible = false;
                viewHideFiltersToolStripMenuItem.Checked = false;
                lvwEvents.Focus();
                if (lvwEvents.SelectedItems.Count > 0)
                {
                    lvwEvents.SelectedItems[0].EnsureVisible();
                    lvwEvents.FocusedItem = lvwEvents.SelectedItems[0];
                }
                this.cmdFilterPanelSizeToggle2.Image = global::EventScavenger.Properties.Resources.DownBtn;
            }
            else
            {
                panFilters.Height = filterExpandedSize;
                panFilterDetails.Visible = true;
                viewHideFiltersToolStripMenuItem.Checked = true;
                if (lvwEvents.SelectedItems.Count > 0)
                {
                    lvwEvents.SelectedItems[0].EnsureVisible();
                    lvwEvents.FocusedItem = lvwEvents.SelectedItems[0];
                }
                cboTypeFilter.Focus();
                this.cmdFilterPanelSizeToggle2.Image = global::EventScavenger.Properties.Resources.UpBtn;
            }
        }
        private void cmdFilterPanelSizeToggle_Click(object sender, EventArgs e)
        {
            if (panFilters.Height == filterExpandedSize)
            {
                panFilters.Height = filterCollapsedSize;
                panFilterDetails.Visible = false;
                viewHideFiltersToolStripMenuItem.Checked = false;
                lvwEvents.Focus();
                if (lvwEvents.SelectedItems.Count > 0)
                {
                    lvwEvents.SelectedItems[0].EnsureVisible();
                    lvwEvents.FocusedItem = lvwEvents.SelectedItems[0];
                }
            }
            else
            {
                panFilters.Height = filterExpandedSize;
                panFilterDetails.Visible = true;
                viewHideFiltersToolStripMenuItem.Checked = true;
                if (lvwEvents.SelectedItems.Count > 0)
                {
                    lvwEvents.SelectedItems[0].EnsureVisible();
                    lvwEvents.FocusedItem = lvwEvents.SelectedItems[0];
                }
                cboTypeFilter.Focus();
                
            }
        }
        private void LoadViews()
        {
            try
            {
                EventLogView selectedView;
                if (cboViews.SelectedIndex > 0)
                {
                    selectedView = (EventLogView)cboViews.SelectedItem;
                }
                else
                    selectedView = new EventLogView();

                initialViewOnStartUp = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "DefaultInitialView.elvw");

                cboViews.Items.Clear();
                cboViews.Items.Add("No filter");
                if (System.IO.File.Exists(initialViewOnStartUp))
                {
                    EventLogView eventLogViewLocal = EventLogView.LoadViewFromFile(initialViewOnStartUp);
                    eventLogViewLocal.Name = "Previous Session";
                    cboViews.Items.Add(eventLogViewLocal);
                }

                if (Properties.Settings.Default.PredefineViewPaths != null)
                {
                    foreach (string path in Properties.Settings.Default.PredefineViewPaths)
                    {
                        if (System.IO.File.Exists(path) && path != initialViewOnStartUp)
                        {
                            try
                            {
                                EventLogView eventLogViewLocal = EventLogView.LoadViewFromFile(path);
                                cboViews.Items.Add(eventLogViewLocal);
                                //if (selectedView.Name == eventLogViewLocal.Name)
                                //{
                                //    cboViews.SelectedItem = eventLogViewLocal;
                                //}
                            }
                            catch { }
                        }
                    }
                }


                //if (lvwProfiles.SelectedItems.Count > 0)
                //{
                //    selectedView = lvwProfiles.SelectedItems[0].Text;
                //}
                //lvwProfiles.Items.Clear();
                //lvwi = new ListViewItem("All/No filter");
                //lvwi.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold);
                //lvwi.Tag = "";
                //lvwProfiles.Items.Add(lvwi);

                //if (Properties.Settings.Default.PredefineViewPaths != null)
                //{
                //    foreach (string path in Properties.Settings.Default.PredefineViewPaths)
                //    {
                //        if (System.IO.File.Exists(path))
                //        {
                //            try
                //            {
                //                EventLogView eventLogView = EventLogView.LoadViewFromFile(path);
                //                ListViewItem lvi = new ListViewItem(eventLogView.Name);
                //                lvi.SubItems.Add(eventLogView.ViewPath);
                //                lvi.Tag = eventLogView;
                //                if (selectedView == eventLogView.Name)
                //                {
                //                    lvi.Selected = true;
                //                }
                //                lvwProfiles.Items.Add(lvi);
                //            }
                //            catch { }
                //        }
                //    }
                //}
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Loading Views", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void ApplyEventLogView(EventLogView selectedView)
        {
            initializing = true;
            sqlEventSource.MachineLogFilters = selectedView.MachineLogs;
            sqlEventSource.ShowAllMachineLogs = selectedView.ShowAllLogs;
            DisplaySelectedMLEs();

            sqlEventSource.EventIdsVisible = selectedView.EventIds;
            sqlEventSource.ViewAllEventIDs = selectedView.ShowAllEventIDs;
            DisplaySelectedEventIDs();

            sqlEventSource.SourceFilters = selectedView.Sources;
            sqlEventSource.ShowAllSources = selectedView.ShowAllSources;
            DisplaySelectedSources();

            sqlEventSource.EventLogEntryType = (EventLogEntryTypes)selectedView.EventLogEntryType;
            cboTypeFilter.SelectedIndex = selectedView.EventLogEntryType;
            txtTextSearch.Text = selectedView.FilterText;            

            CheckStayUpToDate();
            initializing = false;
            RefreshList();
            
        }
        private void applyFilterProfileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lvwProfiles.SelectedItems.Count > 0)
            {
                if (lvwProfiles.SelectedItems[0].Tag is EventLogView)
                {
                    EventLogView selectedView = (EventLogView)lvwProfiles.SelectedItems[0].Tag;
                    ApplyEventLogView(selectedView);
                    //initializing = true;
                    //sqlEventSource.MachineLogFilters = selectedView.MachineLogs;
                    //sqlEventSource.ShowAllMachineLogs = selectedView.ShowAllLogs;
                    //DisplaySelectedMLEs();

                    //sqlEventSource.EventIdsVisible = selectedView.EventIds;
                    //sqlEventSource.ViewAllEventIDs = selectedView.ShowAllEventIDs;
                    //DisplaySelectedEventIDs();

                    //sqlEventSource.SourceFilters = selectedView.Sources;
                    //sqlEventSource.ShowAllSources = selectedView.ShowAllSources;
                    //DisplaySelectedSources();

                    //sqlEventSource.EventLogEntryType = (EventLogEntryTypes)selectedView.EventLogEntryType;
                    //cboTypeFilter.SelectedIndex = selectedView.EventLogEntryType;
                    //txtTextSearch.Text = selectedView.FilterText;
                    //initializing = false;
                }
                else
                {
                    PresetProfile selectedProfile = new PresetProfile("");
                    if (lvwProfiles.SelectedItems[0].Tag.ToString() != "")
                    {
                        selectedProfile = PresetProfile.LoadFilterProfileFromFile(lvwProfiles.SelectedItems[0].Tag.ToString());
                    }
                    initializing = true;
                    sqlEventSource.MachineLogFilters = selectedProfile.MachineLogs;
                    sqlEventSource.ShowAllMachineLogs = selectedProfile.ShowAllLogs;
                    DisplaySelectedMLEs();
                    sqlEventSource.EventIdsVisible = selectedProfile.EventIds;
                    sqlEventSource.ViewAllEventIDs = selectedProfile.ShowAllEventIDs;
                    DisplaySelectedEventIDs();
                    sqlEventSource.SourceFilters = selectedProfile.Sources;
                    sqlEventSource.ShowAllSources = selectedProfile.ShowAllSources;
                    DisplaySelectedSources();
                    sqlEventSource.EventLogEntryType = (EventLogEntryTypes)selectedProfile.EventLogEntryType;
                    cboTypeFilter.SelectedIndex = selectedProfile.EventLogEntryType;
                    initializing = false;

                }
                RefreshList();
            }
        }
        private void ShowCurrentFilterSummary()
        {
            string summary = "[Filters - F6]";
            if (cboTypeFilter.SelectedIndex > 0)
                summary += string.Format(" Type: {0}", cboTypeFilter.Text);
            if (txtTextSearch.Text.Length > 0)
                summary += string.Format(" Text: '{0}'", txtTextSearch.Text);
            if (sqlEventSource != null)
            {
                if (!sqlEventSource.ShowAllMachineLogs && listTextBoxMLE.Text.Length > 0)
                    summary += string.Format(" Logs: {0}", listTextBoxMLE.Text);
                if (!sqlEventSource.ShowAllSources && listTextBoxSource.Text.Length > 0)
                    summary += string.Format(" Sources: {0}", listTextBoxSource.Text);
                if (!sqlEventSource.ViewAllEventIDs && listTextBoxEventID.Text.Length > 0)
                    summary += string.Format(" IDs: {0}", listTextBoxEventID.Text);
            }
            if (chkStayUpToDate.Checked)
                summary += " *Current*";

            //cmdFilterPanelSizeToggle.Text = summary;
            lblFilterSummary.Text = summary;
        }
        #endregion

        #region Machine log filter
        private void DisplaySelectedMLEs()
        {
            listTextBoxMLE.AllEnabled = sqlEventSource.ShowAllMachineLogs;
            listTextBoxMLE.SetText(
                (from mle in sqlEventSource.MachineLogFilters
                 select mle.Machine + "\\" + mle.LogName).ToList<string>()
               );
        }
        private string FormatMLE(string input)
        {
            foreach (MachineLogEntry mle in sqlEventSource.AvailableMachineLog)
            {
                if ((!input.StartsWith("*")) && (mle.Machine + "\\" + mle.LogName).StartsWith(input, StringComparison.CurrentCultureIgnoreCase))
                {
                    sqlEventSource.MachineLogFilters.Add(mle);
                    return mle.Machine + "\\" + mle.LogName;
                }
                else if ((input.StartsWith("*")) && (mle.Machine + "\\" + mle.LogName).ToLower().Contains(input.Substring(1).ToLower()))
                {
                    sqlEventSource.MachineLogFilters.Add(mle);
                    return mle.Machine + "\\" + mle.LogName;
                }

            }
            return "";
        }
        private void listTextBoxMLE_PrepareInput()
        {
            sqlEventSource.MachineLogFilters = new List<MachineLogEntry>();
        }
        private void listTextBoxMLE_ParseOutput()
        {
            sqlEventSource.ShowAllMachineLogs = listTextBoxMLE.AllEnabled;
            RefreshList();
        }
        #endregion

        #region Source filter
        private void DisplaySelectedSources()
        {
            listTextBoxSource.AllEnabled = sqlEventSource.ShowAllSources;
            listTextBoxSource.SetText(sqlEventSource.SourceFilters);
        }
        private string FormatSource(string input)
        {
            foreach (string source in sqlEventSource.AvailableSources)
            {
                if ((!input.StartsWith("*")) && source.StartsWith(input, StringComparison.CurrentCultureIgnoreCase))
                {
                    if (!sqlEventSource.SourceFilters.Contains(source))
                        sqlEventSource.SourceFilters.Add(source);
                    return source;
                }
                else if (input.StartsWith("*") && source.ToLower().Contains(input.Substring(1).ToLower()))
                {
                    if (!sqlEventSource.SourceFilters.Contains(source))
                        sqlEventSource.SourceFilters.Add(source);
                    return source;
                }
            }
            return "";
        }
        private void listTextBoxSource_PrepareInput()
        {
            sqlEventSource.SourceFilters = new List<string>();

        }
        private void listTextBoxSource_ParseOutput()
        {
            sqlEventSource.ShowAllSources = listTextBoxSource.AllEnabled;
            RefreshList();
        }
        #endregion

        #region Event ID filter
        private void DisplaySelectedEventIDs()
        {
            listTextBoxEventID.AllEnabled = sqlEventSource.ViewAllEventIDs;
            listTextBoxEventID.SetText(
                (from eventId in sqlEventSource.EventIdsVisible
                 select eventId.ToString()).ToList<string>()
               );
        }
        private string FormatEventID(string input)
        {
            int parsedInt = 0;
            if (int.TryParse(input, out parsedInt))
            {
                foreach (int eventId in sqlEventSource.AvailableEventIDs)
                {
                    if (eventId == parsedInt)
                    {
                        sqlEventSource.EventIdsVisible.Add(eventId);
                        return eventId.ToString();
                    }
                }
            }
            return "";
        }
        private void listTextBoxEventID_PrepareInput()
        {
            sqlEventSource.EventIdsVisible = new List<int>();
        }
        private void listTextBoxEventID_ParseOutput()
        {
            sqlEventSource.ViewAllEventIDs = listTextBoxEventID.AllEnabled;
            RefreshList();
        }
        #endregion

        #region Export data
        private void ExportEntries(bool all)
        {
            int batchPos = 0;
            saveTXTFileDialog.FileName = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "EventLog.csv");
            if (saveTXTFileDialog.ShowDialog() == DialogResult.OK)
            {
                StringBuilder sb = new StringBuilder();
                System.IO.File.WriteAllText(saveTXTFileDialog.FileName, "MachineName, Log, Type, DateTime, Source, EventID, Message\r\n", Encoding.UTF8);

                for (int listcounter = 0; listcounter < lvwEvents.Items.Count; listcounter++)
                {
                    ListViewItem lvwi = lvwEvents.Items[listcounter];
                    if (all || lvwi.Selected)
                    {
                        EventEntry entry = (EventEntry)lvwi.Tag;
                        sb.Append(entry.MachineName + ", ");
                        sb.Append(entry.LogName + ", ");
                        sb.Append(entry.EventTypeName + ", ");
                        sb.Append(entry.TimeGenerated.ToString("yyyy-MM-dd HH:mm:ss") + ", ");
                        sb.Append(entry.SourceName + ", ");
                        sb.Append(entry.EventID.ToString() + ", ");
                        string msg = entry.Message;
                        msg = msg.Replace(',', '_');
                        msg = msg.Replace("\r\n", "->");
                        msg = msg.Replace("\r", "->");
                        msg = msg.Replace("\n", "->");
                        sb.Append(msg);
                        sb.AppendLine();
                        batchPos++;

                        if (batchPos >= 100)
                        {
                            System.IO.File.AppendAllText(saveTXTFileDialog.FileName, sb.ToString(), Encoding.UTF8);
                            sb = new StringBuilder();
                            batchPos = 0;
                        }
                    }
                }                
                if (batchPos > 0)
                    System.IO.File.AppendAllText(saveTXTFileDialog.FileName, sb.ToString(), Encoding.UTF8);
            }
        }
        #endregion        

        #region Search for Text
        private void SearchForMessageText(string textToSearch)
        {
            int startPos = -1;
            bool deepSearch = searchFullTextToolStripMenuItem.Checked;
            if (textToSearch.Length > 0)
            {
                if (lvwEvents.SelectedItems.Count > 0)
                {
                    startPos = lvwEvents.SelectedItems[0].Index;
                }
                for (int i = startPos + 1; i < lvwEvents.Items.Count; i++)
                {
                    string entryText = "";
                    if (!deepSearch)
                        entryText = lvwEvents.Items[i].SubItems[7].Text.ToUpper();
                    else if (lvwEvents.Items[i].Tag is EventEntry)
                    {
                        EventEntry entry = (EventEntry)lvwEvents.Items[i].Tag;
                        entryText = entry.Message.ToUpper();
                    }

                    if (entryText.Contains(textToSearch.ToUpper()))
                    {
                        lvwEvents.SelectedItems.Clear();
                        lvwEvents.Items[i].Selected = true;
                        lvwEvents.Items[i].EnsureVisible();
                        return;
                    }
                }
                if (startPos >= 0)
                {
                    for (int i = 0; i < startPos; i++)
                    {
                        string entryText = "";
                        if (!deepSearch)
                            entryText = lvwEvents.Items[i].SubItems[7].Text.ToUpper();
                        else if (lvwEvents.Items[i].Tag is EventEntry)
                        {
                            EventEntry entry = (EventEntry)lvwEvents.Items[i].Tag;
                            entryText = entry.Message.ToUpper();
                        }

                        if (entryText.Contains(textToSearch.ToUpper()))
                        {
                            lvwEvents.SelectedItems.Clear();
                            lvwEvents.Items[i].Selected = true;
                            lvwEvents.Items[i].EnsureVisible();
                            return;
                        }
                    }
                }
                MessageBox.Show("Specified text was not found!", "No Found", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            else
            {
                findToolStripMenuItem_Click(null, new EventArgs());
            }
        }
        #endregion       

        #region EventAnalizer events
        private void eventAnalizer_UpdateAnalizerData(ref EventEntry[] eventEntries)
        {
            eventEntries = list.ToArray();
        }
        #endregion        

        #region Rich text box context menu events
        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            rtxtEntryDetail.Copy();
        }
        private void selectAllToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            rtxtEntryDetail.SelectAll();
        }
        private void showDetailsForAllSelectedItemsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DisplaySelectedItemDetails(int.MaxValue);
        }
        #endregion

        #region HighLightToolbar events
        private void toolStripButtonHighLightMachineLogs_Click(object sender, EventArgs e)
        {
            MachineLogFilter machineLogFilter = new MachineLogFilter();
            machineLogFilter.AllEnabled = false;
            machineLogFilter.AllowNone = true;
            machineLogFilter.SelectedMachineLogs = highLightMachineLogs;
            if (machineLogFilter.Show(sqlEventSource) == DialogResult.OK)
            {
                highLightMachineLogs = machineLogFilter.SelectedMachineLogs;
                ApplyHighLights();
            }
        }
        private void toolStripButtonHighLightEventIDs_Click(object sender, EventArgs e)
        {
            EventIDFilter eventIDFilter = new EventIDFilter();
            eventIDFilter.SelectedIds = highLightIds;
            eventIDFilter.AllowNone = true;
            if (eventIDFilter.Show(sqlEventSource) == DialogResult.OK)
            {
                highLightIds = eventIDFilter.SelectedIds;
                ApplyHighLights();
            }
        }
        private void toolStripButtonHighLightSources_Click(object sender, EventArgs e)
        {
            EventSourceFilter eventSourceFilter = new EventSourceFilter();
            eventSourceFilter.SelectedSources = highLightSources;
            eventSourceFilter.AllowNone = true;
            if (eventSourceFilter.Show(sqlEventSource) == DialogResult.OK)
            {
                highLightSources = eventSourceFilter.SelectedSources;
                ApplyHighLights();
            }
        } 
        #endregion

        #region Collapsible groups
        private string GetListViewGroupDescription()
        {
            if (groupByNoneToolStripMenuItem.Checked)
            {
                return "";
            }
            else if (groupByMachineToolStripMenuItem.Checked)
            {
                return "Machine";
            }
            else if (groupByLogToolStripMenuItem.Checked)
            {
                return "Log";
            }
            else if (groupByTypeToolStripMenuItem.Checked)
            {
                return "Type";
            }
            else if (groupBySourceToolStripMenuItem.Checked)
            {
                return "Source";
            }
            else if (groupByEventIDToolStripMenuItem.Checked)
            {
                return "Event ID";
            }
            else if (groupByDateToolStripMenuItem.Checked)
            {
                return "Date";
            }
            else if (groupByHourToolStripMenuItem.Checked)
            {
                return "Hour";
            }
            else if (groupByMonthToolStripMenuItem.Checked)
            {
                return "Month";
            }
            else if (groupBySummaryToolStripMenuItem.Checked)
            {
                return "Summary";
            }
            else
                return "";
        }
        private ListViewGroup GetListViewGroupBySelectedGroup(ListViewItem lvi)
        {
            if (groupByNoneToolStripMenuItem.Checked)
            {
                return null;
            }
            else if (groupByMachineToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[0].Text);
            }
            else if (groupByLogToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[1].Text);
            }
            else if (groupByTypeToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[2].Text);
            }
            else if (groupBySourceToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[5].Text);
            }
            else if (groupByEventIDToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[6].Text);
            }
            else if (groupByDateToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[3].Text);
            }
            else if (groupByHourToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(string.Format("{0} {1}:00", lvi.SubItems[3].Text, lvi.SubItems[4].Text.Substring(0,2)));
            }
            else if (groupByMonthToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(string.Format("{0}", lvi.SubItems[3].Text.Substring(0,7)));
            }
            else if (groupBySummaryToolStripMenuItem.Checked)
            {
                return lvwEvents.GetCreateGroup(lvi.SubItems[7].Text);
            }
            else
                return null;
        }
        private void SetGroupByToolStripChecks(ItemsGroupBy itemsGroupBy)
        {
            expandAllToolStripMenuItem.Enabled = itemsGroupBy != ItemsGroupBy.None;
            collapseAllToolStripMenuItem.Enabled = itemsGroupBy != ItemsGroupBy.None;
            groupByNoneToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.None;
            groupByMachineToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Machine;
            groupByLogToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Log;
            groupByTypeToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Type;
            groupBySourceToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Source;
            groupByEventIDToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.EventID;
            groupByDateToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Day;
            groupByHourToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Hour;
            groupByMonthToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Month;
            groupBySummaryToolStripMenuItem.Checked = itemsGroupBy == ItemsGroupBy.Summary;
        }
        private void expandAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lvwEvents.BeginUpdate();
            lvwEvents.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Normal);
            lvwEvents.EndUpdate();
        }
        private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            lvwEvents.BeginUpdate();
            lvwEvents.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Collapsed);
            lvwEvents.EndUpdate();
            
        }
        private void groupByNoneToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.None);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.None;
            }
        }
        private void groupByMachineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Machine);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Machine;
            }
        }
        private void groupByLogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Log);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Log;
            }
        }
        private void groupByTypeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Type);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Type;
            }
        }
        private void groupBySourceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Source);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Source;
            }
        }
        private void groupByEventIDToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.EventID);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.EventID;
            }
        }
        private void groupByDateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Day);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Day;
            }
        }
        private void groupByHourToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Hour);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Hour;
            }
        }
        private void groupByMonthToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Month);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Month;
            }
        }
        private void groupBySummaryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!initializing)
            {
                SetGroupByToolStripChecks(ItemsGroupBy.Summary);
                RefreshList();
                Properties.Settings.Default.ItemsGroupBy = (int)ItemsGroupBy.Summary;
            }  
        }
        private void SetListViewGroupOptionsCombo(string groupDesc, int subitemIndex1, int subitemIndex2, SortOrder sortOrder, string format, int length1, int length2)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                lvwEvents.ShowGroups = true;
                lvwEvents.GroupDescription = groupDesc;
                lvwEvents.BeginUpdate();
                foreach (ListViewItem lvi in lvwEvents.Items)
                {
                    int length1adj = lvi.SubItems[subitemIndex1].Text.Length > length1 ? length1 : lvi.SubItems[subitemIndex1].Text.Length;
                    int length2adj = lvi.SubItems[subitemIndex2].Text.Length > length2 ? length2 : lvi.SubItems[subitemIndex2].Text.Length;
                    lvi.Group = lvwEvents.GetCreateGroup(string.Format(format, lvi.SubItems[subitemIndex1].Text.Substring(0, length1adj), lvi.SubItems[subitemIndex2].Text.Substring(0, length2adj)));
                }
                lvwEvents.EndUpdate();

                foreach (ListViewGroup lvg in lvwEvents.Groups)
                {
                    lvwEvents.SetGroupFooter(lvg, string.Format("  {0} item(s)", lvg.Items.Count));
                }

                DelayExecute.Execute(this, 200, (DelayExecuteDelegate)SetListViewGroupStateDefault);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
        private void SetListViewGroupOptions(string groupDesc, int subitemIndex, SortOrder sortOrder)
        {
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                lvwEvents.ShowGroups = true;
                lvwEvents.GroupDescription = groupDesc;
                lvwEvents.BeginUpdate();
                foreach (ListViewItem lvi in lvwEvents.Items)
                {
                    lvi.Group = lvwEvents.GetCreateGroup(lvi.SubItems[subitemIndex].Text);
                }
                lvwEvents.EndUpdate();

                foreach (ListViewGroup lvg in lvwEvents.Groups)
                {
                    lvwEvents.SetGroupFooter(lvg, string.Format("  {0} item(s)", lvg.Items.Count));
                }

                DelayExecute.Execute(this, 200, (DelayExecuteDelegate)SetListViewGroupStateDefault);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }
        private void SetListViewGroupStateDefault()
        {
            //Problem - Displaying the group count cause a freeze
            //No solution for this issue yet
            lvwEvents.BeginUpdate();
            foreach (ListViewGroup lvg in lvwEvents.Groups)
            {
                lvwEvents.SetGroupFooter(lvg, string.Format("  {0} item(s)", lvg.Items.Count));
            }            

            //bug in Footer code - if list is big then painting gets screwed up
            //Fix is to trigger a redraw/refresh of the control
            if (lvwEvents.Groups.Count > 0)
            {
                //int lastIndex = lvwEvents.Groups.Count - 1;
                //lvwEvents.SetGroupState(lvwEvents.Groups[lastIndex], ListViewGroupState.Collapsible | ListViewGroupState.Collapsed);
                //Application.DoEvents();
                //lvwEvents.SetGroupState(lvwEvents.Groups[lastIndex], ListViewGroupState.Collapsible | ListViewGroupState.Normal);
            }
            lvwEvents.SetGroupState(ListViewGroupState.Collapsible | ListViewGroupState.Normal);
            lvwEvents.EndUpdate();
        }
        #endregion

        #region Pie chart
        private void perMachineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[0].Text into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                   g.Key,
                                                   g.Count()
                                               )).ToList();
            ShowPieGraph("Machines", pieList);
        }
        private void perEventlogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[1].Text into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Eventlog", pieList);
        }
        private void perTypeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[2].Text into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Type", pieList);
        }
        private void perDateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[3].Text into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Date", pieList);
        }
        private void perHourToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[4].Text.Substring(0, 2) + ":00" into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Hour", pieList);
        }
        private void perDateHourToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[3].Text + " " + r.SubItems[4].Text.Substring(0, 2) + ":00" into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Date + Hour", pieList);
        }
        private void perSourceToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[5].Text into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Source", pieList);
        }
        private void perEventIDToolStripMenuItem_Click(object sender, EventArgs e)
        {
            List<DictionaryEntry> pieList = (from ListViewItem r in lvwEvents.Items
                                             group r by r.SubItems[6].Text into g
                                             orderby g.Key
                                             select new DictionaryEntry(
                                                 g.Key,
                                                 g.Count()
                                             )).ToList();
            ShowPieGraph("Event ID", pieList);
        }

        #region Show Pie chart
        private void ShowPieGraph(string caption, List<DictionaryEntry> pieList)
        {
            decimal[] pieValues;
            float[] pieDisplacements;
            string[] pieTexts;
            string[] pieTooltips;
            try
            {
                if (pieList.Count > 0)
                {
                    ArrayList values = new ArrayList();
                    ArrayList displacements = new ArrayList();
                    ArrayList texts = new ArrayList();
                    ArrayList tooltips = new ArrayList();
                    long totalValue = 0;
                    long restValue = 0;
                    double perc;
                    string text;
                    foreach (DictionaryEntry row in pieList)
                    {
                        totalValue += long.Parse(row.Value.ToString());
                    }
                    if (totalValue == 0)
                    {
                        return;
                    }
                    foreach (DictionaryEntry row in pieList)
                    {
                        long thisvalue = long.Parse(row.Value.ToString());
                        if (((100.0 * thisvalue) / totalValue) > (double)minPieRestPerc)
                        {
                            values.Add((decimal)thisvalue);
                            perc = (((100.0 * thisvalue) / totalValue));
                            displacements.Add(0f);
                            text = string.Format("{0} ({1}%)",
                                    row.Key.ToString(),
                                    perc.ToString("0.0")
                                    );

                            texts.Add(text);
                            tooltips.Add(text);
                        }
                        else
                        {
                            restValue += thisvalue;
                        }
                    }
                    if (restValue > 0)
                    {
                        values.Add((decimal)restValue);
                        perc = (((100.0 * restValue) / totalValue));
                        displacements.Add(0f);
                        text = string.Format("Other ({0}%)",
                                    perc.ToString("0.0")
                                    );
                        texts.Add(text);
                        tooltips.Add(text);
                    }

                    pieValues = (decimal[])values.ToArray(typeof(decimal));
                    pieDisplacements = (float[])displacements.ToArray(typeof(float));
                    pieTexts = (string[])texts.ToArray(typeof(string));
                    pieTooltips = (string[])tooltips.ToArray(typeof(string));
                    PieGraphView pieGraphView = new PieGraphView();
                    pieGraphView.ShowPieChart(caption, pieTexts, pieTooltips, pieValues, pieDisplacements);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion          

        
        #endregion        


    }
}
